<?php
/**
 * content: 所有类的基类，主要具有的方法，采用thinkphp的路由规范进行搭建
 * author : Songyicong
 * email  : m13726262373@163.com 
 * time   : 2018-04-16
 */
namespace app\api\controller;

use think\Controller;
use app\api\extra\Send;
use app\api\extra\Factory;
use think\Request;
use think\Db;
use think\Cache;
use app\api\model\v1\Admin;
use app\api\model\v1\UrlAuth;
class BaseController extends Controller{

    use Send;

    /** 操作方法：增，删，改，查（列表，单独） */
    public $methodToAction = [
        'get' => 'read',//读取一个或读取全部
        'post'=> 'save',//新增一个
        'put' => 'update',//
        'delete'=>'delete',
        'patch' => 'patch',
        'head' => 'head',
        'options' => 'options',
    ];

    /** 是否开启第一次权限访问设置值 */
    public $isFirstAuth = true;

    /** 允许访问的请求类型 */
    public $restMethodList = 'get|post|put|delete|patch|head|options';

    /** 是否验证 token */
    public $tokenAuth = true;
    /** 是否验证 IP */
    public $ipAuth = false;
    /** 是否采用头验证 */
    public $isHeader = false;
    /** 前台权限验证 */
    public $userAuth = false;
    /** 后台权限验证 */
    public $adminAuth = false;
    /** 是否允许跨域 */
    public $isCrossDomain = true;

    /** 请求 */
    protected $request;
    /** 参数 */
    protected $params;
    
    /** 当前请求类型 */
    protected $method ;

    /** 当前资源类型 */
    protected $type ;
    
    public static $app;
    
    public $auth_num = 0;

    /** 返回制约类型 */
    protected $restTypeList = 'json';
    /** Rest 允许输出的资源类型列表 */
    protected $restOutputType = [
        'json' => 'application/json',
    ];
    /** 客户端信息 */
    protected $clientInfo;

    /** 控制器初始化操作 */
    public function _initialize(){
        if($this->isCrossDomain){
            header('Access-Control-Allow-Origin:*');
        }
        if(empty($this->request)){
            $request = Request::instance();
            $this->request = $request;
        }   
        $this->params = $this->request->param();
        if($this->isFirstAuth){
            // 第一次权限判断
            $this->firstAuth();
        }
        
        $this->init();
        
    }

    /**
     * 初始化方法
     * 检查请求类型，数据格式等操作
     */
    public function init(){
        $auth_num = [];
        if($this->tokenAuth && !($auth_num=$this->checkTokenAuth())){
            // 验证 token 是否合法
            return self::returnmsg(403, 'access_token access is illegal');
        }
        if($this->ipAuth && !$this->checkIp($auth_num)){
            // 如果ipAuth设置为true,表示需要IP检测
            return self::returnmsg(403, 'illegal access to ip');
        }
        
        // 获取URL返回后缀
        $ext = $this->request->ext();
        if(''  == $ext){
            //自动检测资源类型
            $this->type = $this->request->type();
        }elseif(!preg_match('/\(' . $this->restTypeList . '\)$/i', $ext)){
             // 资源类型非法 则用默认资源类型访问
             $this->type = $this->restDefaultType;
        }else{
            $this->type = $ext;
        }

        // 设置响应类型
        $this->setType();
        // 请求方法检测
        $method = strtolower($this->request->method());
        $this->method = $method;
        if(false === stripos($this->restMethodList,$method)){
            // 如果访问方法不存在合法方法，返回错误
            return self::returnmsg(405,'Method Not Allowed',["access-control-request-method" => $this->restMethodList]);
        }

        if($this->userAuth){
            // 验证用户是否有访问权限
            $this->clientInfo = $this->checkUserAuth($auth_num);
        }else if($this->adminAuth){
            // 验证后台是否有访问权限
            $this->clientInfo = $this->checkAdminAuth($auth_num);
        }

    }

    /**
     * 验证token是否合法
     */
    public function checkTokenAuth(){
        // 获取工厂类
        $baseAuth = Factory::getInstance(\app\api\controller\Check::class);
        $auth_num = $baseAuth->checkToken($this->request,$this->isHeader);
        return $auth_num;
    }

    /**
     * 验证 后台用户 是否有权限操作，如果有，返回当前用户权限
     */
    public function checkAdminAuth($auth_num=0){
        // 获取工厂类
        $baseAuth = Factory::getInstance(\app\api\controller\Check::class);
        $clientInfo = $baseAuth->checkAdminAuth($this->request,$this->isHeader,$auth_num);
        return $clientInfo;
    }

    /**
     * 验证 User 是否有权限操作，如果有，返回当前用户权限
     */
    public function checkUserAuth($auth_num=0){
        // 获取工厂类
        $baseAuth = Factory::getInstance(\app\api\controller\Check::class);
        $clientInfo = $baseAuth->checkUserAuth($this->request,$this->isHeader,$auth_num);
        // $baseAuth = Factory::getInstance(\app\api\controller\Oauth::class);
        // $clientInfo = $baseAuth->authenticate($this->isHeader);
        return $clientInfo;
    }
    
    /** 空操作 */
    public function _empty(){
        return $this->sendSuccess([],'empty method!',404);
    }

    /** 判断ip是否合法 */
    public function checkIp($auth_num){
        $flag = false;
        if(!is_array($auth_num) && $auth_num['admin_id']){
            return $flag;
        }
        //这里可以查找数据库的 ip 是否有该IP，通过
        $admin = new Admin();
        if($results = $admin->getIpAuth($this->request->ip(),$auth_num['admin_id'])){
            $ips = explode(',',$results['ip']);
            $flag = in_array($this->request->ip(),$ips)? true:false;
        }
        return $flag;
    }

    /** 判断第一次访问是否需要增加权限 */
    public function firstAuth(){
        $route = $this->request->routeInfo();
        if(empty(UrlAuth::isUrlAuth($route['route']))){
            $data['create_time'] = time();
            $data['action'] = $this->request->action();
            $data['module'] = $this->request->module();
            $data['controller'] = $this->request->controller();
            $data['version'] = $this->params['version'];
            $data['url'] = $route['route'];
            $data['auth_num'] = 999;
            $data['status'] = 1;
            $data['name'] = "初始化接口";
            $uid = Db::name('url_auth')->insertGetId($data);
        }
    }

    //下面的父类都是子类的方法集成
    public function index(){
    }
    public function create(){
    }
    public function save(){
    }
    public function read($id){
    }
    public function edit($id){
    }
    public function update($id){
    }
    public function delete($id){
    }

}
